package com.cman777.springc.encode.advice.d4t;

import com.cman777.springc.common.helper.AESUtil;
import com.cman777.springc.common.helper.RsaUtils;
import com.cman777.springc.encode.advice.AResponseAdvice;
import com.cman777.springc.encode.advice.d4t.properties.EncodeProperties;
import com.cman777.springc.encode.exception.DecryptEncryptException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;

import java.util.Optional;

@ControllerAdvice(basePackages = "${com.cman777.encode.basePackages}:")
@Order(Integer.MIN_VALUE)
@Slf4j
public class ResponseAdvice extends AResponseAdvice {

    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private EncodeProperties encodeProperties;

    @SneakyThrows
    @Override
    public String getPlaintext(Object o) {
        return objectMapper.writeValueAsString(o);
    }



    @Override
    public boolean needEncryptOtherCondition() {
        return encodeProperties.isEnableEncrypt();
    }

    @Override
    public Object encryptStringAndRetObj(String s, ServerHttpRequest request) {
        String aesKey = Optional.ofNullable(AesKeyHolder.getAesKey()).orElseGet(() -> {
            String codeEncryptedStr = request.getHeaders().getFirst("codeEncryptedStr");
            if (StringUtils.isEmpty(codeEncryptedStr)) {
                throw new DecryptEncryptException("请求头缺少codeEncryptedStr");
            }
            return RsaUtils.decryptByPrivateKey(encodeProperties.getPrivateKey(), codeEncryptedStr);
        });
        Optional.ofNullable(aesKey).ifPresent((a) -> log.info("aesKey={}", a));
        Optional.ofNullable(aesKey).orElseThrow(() -> new DecryptEncryptException("rsa解密codeEncryptedStr失败"));
        ObjectNode resultJson = null;
        try{
            resultJson = (ObjectNode) objectMapper.readTree(s);
        }catch (Exception e){
            log.error("response不是个json");
            resultJson = null;
        }

        Optional.ofNullable(resultJson).orElseThrow(()->new DecryptEncryptException("response不是个json"));
        String dataJsonStr = null;
        try {
            dataJsonStr = objectMapper.writeValueAsString(resultJson.get("data"));
        }catch (Exception e){
            throw new DecryptEncryptException(e.getMessage());
        }
        if(StringUtils.isEmpty(dataJsonStr)){
            dataJsonStr = "";
        }
        String encryptedStr = AESUtil.encrypt(dataJsonStr, aesKey);
        ObjectNode dataNew =  objectMapper.createObjectNode();
        dataNew.put("paramEncryptedStr", encryptedStr);
        resultJson.replace("data", dataNew);
        resultJson.put("encr",true);
        return resultJson;
    }




}
